﻿using DDDSample.Domain.Cargo;
using FluentNHibernate;
using FluentNHibernate.Mapping;

namespace DDDSample.Domain.NHibernate.Mappings
{
    public sealed class CargoMap : ClassMap<Cargo.Cargo>
    {
        public CargoMap()
        {
            Id(x => x.Id).GeneratedBy.Guid();
            Component(x => x.Delivery, m =>
            {
                m.Map(Reveal.Member<Delivery>("_misdirected"), "IsMisdirected")
                 .Access.Field()
                 .Not.Nullable();
                m.Map(Reveal.Member<Delivery>("_eta"), "Eta")
                 .Access.Field();
                m.Map(Reveal.Member<Delivery>("_calculatedAt"), "CalculatedAt")
                 .Access.Field()
                 .Not.Nullable();
                m.Map(Reveal.Member<Delivery>("_isUnloadedAtDestination"), "UnloadedAtDest")
                 .Access.Field()
                 .Not.Nullable();
                m.Map(Reveal.Member<Delivery>("_routingStatus"), "RoutingStatus")
                 .Access.Field()
                 .Not.Nullable();
                m.Map(Reveal.Member<Delivery>("_transportStatus"), "TransportStatus")
                 .Access.Field()
                 .Not.Nullable();
                m.References(Reveal.Member<Delivery>("_lastKnownLocation"), "LastKnownLocationId")
                 .Class<Location.Location>()
                 .Access.Field()
                 .Cascade.None();
                m.References(Reveal.Member<Delivery>("_lastEvent"), "LastEvetId")
                 .Class<HandlingEvent.HandlingEvent>()
                 .Access.Field()
                 .Cascade.None();
                m.Component<HandlingActivity>(Reveal.Member<Delivery>("_nextExpectedActivity"), o =>
                {
                    o.Map(Reveal.Member<HandlingActivity>("_eventType"), "NextExpectedHandlingEventType")
                     .Access.Field();
                    o.References(Reveal.Member<HandlingActivity>("_location"), "NextExpectedLocationId")
                     .Class<Location.Location>()
                     .Cascade.None()
                     .Access.Field();
                }).Access.Field();
            });
            Component(x => x.RouteSpecification, m =>
            {
                m.Map(Reveal.Member<RouteSpecification>("_arrivalDeadline"), "SpecArrivalDeadline")
                 .Not.Nullable()
                 .Access.Field();
                m.References(Reveal.Member<RouteSpecification>("_origin"), "SpecOriginId")
                 .Class<Location.Location>()
                 .Not.Nullable()
                 .Access.Field();
                m.References(Reveal.Member<RouteSpecification>("_destination"), "SpecDestinationId")
                 .Class<Location.Location>()
                 .Not.Nullable()
                 .Access.Field();
            });
            Component(x => x.Itinerary, m =>
            {
                m.HasMany<Leg>(Reveal.Member<Itinerary>("_legs"))
                 .Component(c =>
                 {
                     c.Map(Reveal.Member<Leg>("_loadDate"), "LoadDate")
                      .Access.Field();
                     c.Map(Reveal.Member<Leg>("_unloadDate"), "UnloadDate")
                      .Access.Field();
                     c.References(Reveal.Member<Leg>("_loadLocation"), "LoadLocation")
                      .Class<Location.Location>()
                      .Access.Field();
                     c.References(Reveal.Member<Leg>("_unloadLocation"), "UnloadLocation")
                      .Class<Location.Location>()
                      .Access.Field();
                 })
                 .Cascade.All()
                 .Access.Field()
                 .Table("Leg")
                 .KeyColumn("CargoId").AsList(s =>
                 {
                     s.Column("LegIndex");
                 });
            });
        }
    }
}